package com.soriya.nestlive.viewmodel

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import com.soriya.nestlive.db.dao.ChannelInfoDao
import com.soriya.nestlive.model.Category
import com.soriya.nestlive.model.Live
import com.soriya.nestlive.model.PageResult
import com.soriya.nestlive.model.ResponseResult
import com.soriya.nestlive.net.UploadApi
import com.soriya.nestlive.repository.LiveByCategoryPagingRepository
import com.soriya.nestlive.repository.LiveRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import javax.inject.Inject

@HiltViewModel
class LiveModel @Inject constructor(
    private val liveRepository: LiveRepository,
    private val liveByCategoryPagingRepository: LiveByCategoryPagingRepository,
    private val uploadApi: UploadApi,
    private val channelInfoDao: ChannelInfoDao
) : ViewModel() {

    private val _recommendLiveList = MutableStateFlow(listOf<Live>())

    val recommendLiveList: StateFlow<List<Live>> = _recommendLiveList

    private val _historyList = MutableStateFlow(listOf<Live>())

    val historyList: StateFlow<List<Live>> = _historyList

    private val _liveDetail: MutableStateFlow<Live?> = MutableStateFlow(null)

    val liveDetail: StateFlow<Live?> = _liveDetail

    init {
        viewModelScope.launch {
            liveRepository.list(0, 5).collectLatest { res ->
                when (res) {
                    is ResponseResult.Success<*> -> {
                        val pageResult = res.data as PageResult<*>
                        _recommendLiveList.value = pageResult.list.map {
                            it as Live
                        }
                    }
                    is ResponseResult.Failed -> {}
                    is ResponseResult.Loading -> {}
                }
            }
        }
    }


    // 分页数据
    fun getLiveListByCategoryId(categoryId: Long) = Pager(
        PagingConfig(
            pageSize = 5, // 页面大小
            prefetchDistance = 2, // 距离底部还有多少条数据加载下一页
            enablePlaceholders = false, // 控件占位 false不占位
            initialLoadSize = 5 // 初始化时加载多少条数据
        )
    ) {
        liveByCategoryPagingRepository.categoryId = categoryId
        liveByCategoryPagingRepository
    }.flow

    fun getLiveByChannelId(channelId: Long) {
        viewModelScope.launch {
            liveRepository.getByChannelId(channelId).collect { res ->

                Log.i("SoRiya", "res: $res")

                when (res) {
                    is ResponseResult.Success<*> -> {
                        val live = res.data as Live?
                        _liveDetail.emit(live)
                    }
                    is ResponseResult.Failed -> {}
                    is ResponseResult.Loading -> {}
                }
            }
        }
    }

    fun createLive(live: Live, file: File?): Flow<Live?> = flow {

        var _live = live

        if (file != null) {
            val requestBody = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
            val createFormData =
                MultipartBody.Part.createFormData("file", file.name, requestBody)
            val coverPath = uploadApi.updateImage(createFormData)

            if (coverPath.code != 200) {
                Log.i("SoRiya", "图片上传失败!")
                return@flow
            }

            _live = live.copy(cover = coverPath.data)
        }

        liveRepository.createLive(live = _live).collect { res ->
            when (res) {
                is ResponseResult.Success<*> -> {
                    if (res.code == 200) emit(_live)
                }
                is ResponseResult.Failed -> {}
                is ResponseResult.Loading -> {}
            }
        }
    }

    fun stopLive(): Flow<Unit?> = flow {
        channelInfoDao.selectOne().collect { channelInfo ->
            if (channelInfo == null) return@collect
            liveRepository.stopLive(channelInfo.channelId).collect {
                emit(null)
            }
        }
    }

    fun getHistory(channelId: Long) {
        viewModelScope.launch {
            liveRepository.getHistory(channelId).collect { res ->
                when (res) {
                    is ResponseResult.Success<*> -> {
                        if (res.code == 200) {
                            res.data as List<*>
                            _historyList.emit(res.data.map { it as Live })
                        }
                    }
                    is ResponseResult.Failed -> {}
                    is ResponseResult.Loading -> {}
                }
            }
        }
    }

}